package com.xihuanjun.sdk.util;

import com.xihuanjun.sdk.entity.SapOrderItemBatch;
import com.xihuanjun.sdk.exception.QuantityNotSufficientException;
import com.xihuanjun.sdk.exception.SapException;
import com.xihuanjun.sdk.service.IBatchNumberService;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * Copyright (C), 2024-09-04
 * FileName: BatchUtils
 * Author:   溪浣君
 * Date:     2024-09-04 9:03
 * Description: 获取批次列表工具类，扣减库存获取批次时使用
 */
@Slf4j
public class BatchUtils {

    /**
     * 可用批次缓存，为了解决同一个出库单有多行重复物料时重复扣减同一批次的问题
     * key:物料编号,仓库号
     */
    private HashMap<String, List<SapOrderItemBatch>> itemBatchs=new HashMap<>();


    private IBatchNumberService batchNumberService;

    public BatchUtils( IBatchNumberService batchNumberService) {
        this.batchNumberService = batchNumberService;
    }

    /**
     * 为物料分配批次列表，批次数量不足抛出QuantityNotSufficientException
     * @param itemCode
     * @param quantity
     * @param whsCode
     * @return
     */
    public List<SapOrderItemBatch> getBatchs(String itemCode, BigDecimal quantity,String whsCode){
        log.debug(MessageFormat.format("分配批次任务，物料{0},数量{1},仓库{2}",itemCode,quantity,whsCode));
        List<SapOrderItemBatch> batchReturn=new ArrayList<>();
        //确定可用批次
        List<SapOrderItemBatch> validBatchs;
        if(itemBatchs.containsKey(itemCode+","+whsCode)==false){
            validBatchs = batchNumberService.getItemBatchNumbers(itemCode, whsCode);
            itemBatchs.put(itemCode+","+whsCode,validBatchs);
        }else{
            validBatchs=itemBatchs.get(itemCode+","+whsCode);
        }
        //从可用批次中分配批次
        for (SapOrderItemBatch batch : validBatchs) {
            if(batch.getQuantity().compareTo(BigDecimal.ZERO)<=0){//当前批次无可用数
                continue;
            }
            log.debug(MessageFormat.format("批次{0},可用数{1}",batch.getBatchNumber(),batch.getQuantity()));
            SapOrderItemBatch useBatch=new SapOrderItemBatch();
            useBatch.setBatchNumber(batch.getBatchNumber());
            //确定当前批次的数量
            if(batch.getQuantity().compareTo(quantity)>=0){//这个批次够用
                useBatch.setQuantity(quantity);
                batchReturn.add(useBatch);
                //扣减可用批次数量
                batch.setQuantity(batch.getQuantity().subtract(quantity));
                //需求量清零
                quantity=BigDecimal.ZERO;
                break;//一个批次就够了，分配完活了
            }else{//这个批次不够用，先全部给出，继续找下一个批次要
                useBatch.setQuantity(batch.getQuantity());
                //更新需求量
                quantity=quantity.subtract(batch.getQuantity());
                //此批次可用数清零
                batch.setQuantity(BigDecimal.ZERO);
                //继续寻找下一个批次
                if(quantity.compareTo(BigDecimal.ZERO)==0){
                    break;
                }
            }
            log.debug("分配出{0}",useBatch.getQuantity());
            batchReturn.add(useBatch);
        }
        if(quantity.compareTo(BigDecimal.ZERO)>0){//依然存在需求量，说明批次列表的数量不够
            throw new QuantityNotSufficientException(MessageFormat.format("物料{0}的可用批次数量小于需求量",itemCode));
        }
        log.debug("批次分配完毕：{}",batchReturn);
        return batchReturn;
    }
}
